#include <iostream>
#include <memory>
#include "Epoller.hpp"
#include "InetAddr.hpp"
#include "Socket.hpp"
#include "Log.hpp"
#include "Connection.hpp"
#include "IOService.hpp"
#include "Reactor.hpp"
// #include "Protocol.hpp"
// #include "Calculator.hpp"

using namespace SocketModule;
using namespace LogMudule;

// 专门负责获取链接的模块
// 链接管理器
class Listener : public Connection
{
public:
    Listener(int port)
        : _port(port)
        , _listensock(std::make_unique<TcpSocket>())
    {
        // 创建出TCP套接字
        _listensock->BuildTcpSocketMethod(_port);
        // 将fd与events传给Connection，用来构造Connection
        SetSockfd(_listensock->Fd());
        SetEvents(EPOLLIN | EPOLLET);
    }
    virtual void Sender() override   // 读
    {}
    virtual void Recver() override   // 发
    {
        // 读就绪，而且是listensock就绪
        // IO处理 --- 获取新连接
        // 你怎么知道，一次来的，就是一个连接呢？你怎么保证你一次读完了呢？
        while (true)
        {
            InetAddr peer;
            int aerrno = 0;
            // accept 非阻塞的时候，就是IO，我们就向处理read一样，处理accept
            int sockfd = _listensock->Accepter(&peer, &aerrno);
            if(sockfd > 0)
            {
                // success
                // 我们毫不意外的是不能直接读取的！
                // sockfd 添加到epoll！
                LOG(LogLevel::DEBUG) << "Accepter success: " << sockfd;
                // 普通的文件描述符，处理IO的，也是connection！
                // 1. 设置文件描述符为非阻塞
                SetNonBlock(sockfd);
                // 2. sockfd包装成为Connection！
                auto conn = std::make_shared<IOService>(sockfd);
                // 3. 插入到EpollServer
                GetOwner()->InsertConnection(conn);
            }
            else
            {   
                // 已经获取完所有的新连接了
                if (aerrno == EAGAIN || aerrno == EWOULDBLOCK)
                {
                    LOG(LogLevel::DEBUG) << "accetper all connection ... done";
                    break;
                }
                // 被信号中断了
                else if (aerrno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "accetper intr by signal, continue";
                    continue;
                }
                // 获取连接失败
                else
                {
                    LOG(LogLevel::WARNING) << "accetper error ... Ignore";
                    break;
                }
            }
        }
    }
    virtual void Excepter() override // 异常处理
    {}
    int Sockfd()    { return _listensock->Fd(); }
    ~Listener()
    {
        _listensock->Close();
    }
private:
    int _port;
    std::unique_ptr<Socket> _listensock;
};